<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>xeokit Example</title>
    <link href="../css/pageStyle.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
    <script src="../libs/dat.gui.min.js" type="text/javascript"></script>
    <link href="../css/dat-gui-light-style.css" rel="stylesheet"/>
</head>
<body>
<input type="checkbox" id="info-button"/>
<label for="info-button" class="info-button"><i class="far fa-3x fa-question-circle"></i></label>
<canvas id="myCanvas"></canvas>
<canvas id="myNavCubeCanvas"></canvas>
<div class="slideout-sidebar">
    <img class="info-icon" src="../../assets/images/camera_icon.png"/>
    <h1>CameraControl</h1>
    <h2>First-person mode</h2>
    <p>In this example, we're loading a BIM model from the file system, then navigating it using
        first-person camera mode.</p>
    <h3>Stats</h3>
    <ul>
        <li>
            <div id="time">Loading JavaScript modules...</div>
        </li>
    </ul>
    <h3>Customize</h3>
    <div id="myDatGuiContainer"></div>
    <h3>Components Used</h3>
    <ul>
        <li>
            <a href="../../docs/class/src/viewer/Viewer.js~Viewer.html"
               target="_other">Viewer</a>
        </li>
        <li>
            <a href="../../docs/class/src/viewer/scene/CameraControl/CameraControl.js~CameraControl.html"
               target="_other">CameraControl</a>
        </li>
        <li>
            <a href="../../docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html"
               target="_other">XKTLoaderPlugin</a>
        </li>
    </ul>
    <h3>Resources</h3>
    <ul>
        <li>
            <a href="http://openifcmodel.cs.auckland.ac.nz/Model/Details/274"
               target="_other">Model source</a>
        </li>
    </ul>
</div>
</body>

<script type="module">

    //------------------------------------------------------------------------------------------------------------------
    // Import the modules we need for this example
    //------------------------------------------------------------------------------------------------------------------

    import {
        Viewer,
        XKTLoaderPlugin,
        Mesh,
        VBOGeometry,
        buildGridGeometry,
        PhongMaterial
    } from "../../dist/xeokit-sdk.min.es.js";

    //------------------------------------------------------------------------------------------------------------------
    // Create a Viewer, arrange the camera
    //------------------------------------------------------------------------------------------------------------------

    const viewer = new Viewer({
        canvasId: "myCanvas",
        transparent: true
    });

    const cameraControl = viewer.cameraControl;
    const scene = viewer.scene;
    const cameraFlight = viewer.cameraFlight;
    const camera = scene.camera;

    cameraControl.navMode = "firstPerson";
    cameraControl.followPointer = true;

    viewer.camera.eye = [-8.23, 10.67, 35.26];
    viewer.camera.look = [4.39, 3.72, 8.89];
    viewer.camera.up = [0.10, 0.97, -0.20];

    //----------------------------------------------------------------------------------------------------------------------
    // Load a model and fit it to view
    //----------------------------------------------------------------------------------------------------------------------

    const xktLoader = new XKTLoaderPlugin(viewer);

    const sceneModel = xktLoader.load({
        id: "myModel",
        src: "../../assets/models/xkt/v10/glTF-Embedded/Duplex_A_20110505.glTFEmbedded.xkt",
        edges: true
    });

    sceneModel.on("loaded", () => { // This synchronizes camera.ortho.scale to the model boundary
        cameraFlight.flyTo(sceneModel);
    });

    //------------------------------------------------------------------------------------------------------------------
    // Create a mesh with grid
    //------------------------------------------------------------------------------------------------------------------

    new Mesh(viewer.scene, {
        geometry: new VBOGeometry(viewer.scene, buildGridGeometry({
            size: 300,
            divisions: 60
        })),
        material: new PhongMaterial(viewer.scene, {
            color: [0.0, 0.0, 0.0],
            emissive: [0.4, 0.4, 0.4]
        }),
        position: [0, -1.6, 0],
        collidable: false
    });


    const t0 = performance.now();
    document.getElementById("time").innerHTML = "Loading model...";
    sceneModel.on("loaded", function () {
        const t1 = performance.now();
        document.getElementById("time").innerHTML = "Model loaded in " + Math.floor(t1 - t0) / 1000.0 + " seconds";
    });

    //------------------------------------------------------------------------------------------------------------------
    // GUI to play with Camera configs
    //------------------------------------------------------------------------------------------------------------------

    const cameraControlParams = new function () {

        this.active = cameraControl.active;
        this.keyboardLayout = cameraControl.keyboardLayout;
        this.ortho = camera.projection === "ortho";
        this.followPointer = cameraControl.followPointer;
        this.constrainVertical = cameraControl.constrainVertical;
        this.doublePickFlyTo = cameraControl.doublePickFlyTo;
        this.panRightClick = cameraControl.panRightClick;

        this.dragRotationRate = cameraControl.dragRotationRate;
        this.keyboardRotationRate = cameraControl.keyboardRotationRate;
        this.rotationInertia = cameraControl.rotationInertia;

        this.keyboardPanRate = cameraControl.keyboardPanRate;
        this.panInertia = cameraControl.panInertia;

        this.keyboardDollyRate = cameraControl.keyboardDollyRate;
        this.mouseWheelDollyRate = cameraControl.mouseWheelDollyRate;
        this.dollyInertia = cameraControl.dollyInertia;
        this.dollyProximityThreshold = cameraControl.dollyProximityThreshold;
        this.dollyMinSpeed = cameraControl.dollyMinSpeed;

    }();

    const update = () => {

        cameraControl.active = cameraControlParams.active;
        cameraControl.keyboardLayout = cameraControlParams.keyboardLayout;
        camera.projection = cameraControlParams.ortho ? "ortho" : "perspective";
        cameraControl.followPointer = cameraControlParams.followPointer;
        cameraControl.constrainVertical = cameraControlParams.constrainVertical;
        cameraControl.doublePickFlyTo = cameraControlParams.doublePickFlyTo;
        cameraControl.panRightClick = cameraControlParams.panRightClick;

        cameraControl.dragRotationRate = cameraControlParams.dragRotationRate;
        cameraControl.keyboardRotationRate = cameraControlParams.keyboardRotationRate;
        cameraControl.rotationInertia = cameraControlParams.rotationInertia;

        cameraControl.keyboardPanRate = cameraControlParams.keyboardPanRate;
        cameraControl.panInertia = cameraControlParams.panInertia;

        cameraControl.keyboardDollyRate = cameraControlParams.keyboardDollyRate;
        cameraControl.mouseWheelDollyRate = cameraControlParams.mouseWheelDollyRate;
        cameraControl.dollyInertia = cameraControlParams.dollyInertia;
        cameraControl.dollyProximityThreshold = cameraControlParams.dollyProximityThreshold;
        cameraControl.dollyMinSpeed = cameraControlParams.dollyMinSpeed;

        requestAnimationFrame(update);
    };

    update();

    const gui = new dat.GUI({autoPlace: false, width: "100%"});

    const cameraControlFolder = gui.addFolder('cameraControl');
    cameraControlFolder.add(cameraControlParams, 'active');
    cameraControlFolder.add(cameraControlParams, 'keyboardLayout', ["qwerty", "azerty"]);
    cameraControlFolder.add(cameraControlParams, 'ortho');
    cameraControlFolder.add(cameraControlParams, 'followPointer');
    cameraControlFolder.add(cameraControlParams, 'constrainVertical');
    cameraControlFolder.add(cameraControlParams, 'doublePickFlyTo');
    cameraControlFolder.add(cameraControlParams, 'panRightClick');
    cameraControlFolder.open();

    const rotationFolder = gui.addFolder('Rotation');
    rotationFolder.add(cameraControlParams, 'dragRotationRate', 0, 720);
    rotationFolder.add(cameraControlParams, 'keyboardRotationRate', 0, 360);
    rotationFolder.add(cameraControlParams, 'rotationInertia', 0, 1);
    rotationFolder.open();

    const panningFolder = gui.addFolder('Panning');
    panningFolder.add(cameraControlParams, 'keyboardPanRate', 0, 50);
    panningFolder.add(cameraControlParams, 'panInertia', 0, 1);
    panningFolder.open();

    const dollyFolder = gui.addFolder('Dolly');
    dollyFolder.add(cameraControlParams, 'keyboardDollyRate', 0, 30);
    dollyFolder.add(cameraControlParams, 'mouseWheelDollyRate', 0, 100);
    dollyFolder.add(cameraControlParams, 'dollyInertia', 0, 1);
    dollyFolder.add(cameraControlParams, 'dollyProximityThreshold', 0, 150);
    dollyFolder.add(cameraControlParams, 'dollyMinSpeed', 0.01, 1.0);
    dollyFolder.open();

    const customContainer = document.getElementById('myDatGuiContainer');
    customContainer.appendChild(gui.domElement);

</script>
</html>
